package com.SPOooON.googletaskseditor;

// TODO add tasklist
// TODO base accounts on accountmanager, not on db content
// TODO task activity
// TODO tasklist properties activity / popup (name rename)
// TODO store sync timestamp
// TODO new task notifications
// TODO order by sortstring
// TODO no data found, no synch enabled whatevz..  message


import java.util.Date;

import com.SPOooON.googletaskssync.GoogleTasksContentProvider;
import com.SPOooON.googletaskssync.R;
import com.SPOooON.googletaskssync.TaskListWrapper;
import com.SPOooON.googletaskssync.TaskWrapper;
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
import com.google.api.client.util.DateTime;
import com.google.api.services.tasks.model.Task;
import com.google.api.services.tasks.model.TaskList;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;

public class GoogleTaskList extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor>{
	
	private static final String TAG = "GoogleTaskList"; 
	
	private static class DataSets {
		public static final int ACCOUNTS = 0;
		public static final int TASKLISTS = 1;
		public static final int TASKS = 2;
	}
	
	private LoaderManager loaderManager;
	
	private ListView taskListView;
	
	//private Button accountButton;
	private Button taskListButton;
	private ImageButton synchButton;
	private Button addTaskButton;
	
	private EditText taskTitleEditText;
	
	private SimpleCursorAdapter accountAdapter;
	private SimpleCursorAdapter taskListAdapter;
	
	private CondensedTaskCursorAdapter taskAdapter;
	
	private String currentAccount;
	private int currentTaskList;
	
	private boolean jumpToLastTask = false;
	private boolean jumpToLastTaskList = false;
	
	private int currentAccountPosition = -1;
	private int currentTaskListPosition = -1;
	
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        this.setContentView(R.layout.googletasklist);
        this.taskListView = (ListView) this.findViewById(R.id.listView);
        
        this.taskListView.setOnItemClickListener(new OnItemClickListener(){

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position,	long id) {
				GoogleTaskList.this.onCondensedTaskClicked(view, position, id);
			}});
        
        this.taskAdapter = new CondensedTaskCursorAdapter(this.getBaseContext());
        
        this.taskListAdapter = new SimpleCursorAdapter(this.getBaseContext()
        		, android.R.layout.simple_list_item_single_choice
        		, null
        		, new String[] { GoogleTasksContentProvider.TaskLists.Columns.TITLE }
        		, new int[] { android.R.id.text1 }
        		, 0);        

        this.accountAdapter = new SimpleCursorAdapter(this.getBaseContext()
        		, android.R.layout.simple_list_item_single_choice
        		, null
        		, new String[] { GoogleTasksContentProvider.Accounts.Columns.ACCOUNT }
        		, new int[] { android.R.id.text1 }
        		, 0);
        
        this.taskListView.setAdapter(this.taskAdapter);     
        
        this.taskListButton = (Button) this.findViewById(R.id.taskListButton);
        //this.accountButton = (Button) this.findViewById(R.id.accountButton);
        this.synchButton = (ImageButton) this.findViewById(R.id.synchButton);
        this.addTaskButton = (Button) this.findViewById(R.id.addTaskButton);
        
        this.taskListButton.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				new TaskListPickerDialog(currentTaskListPosition
						, new PickerCallback(){

							@Override
							public void onItemClickCallback(int newPosition) {
								Cursor c = GoogleTaskList.this.taskListAdapter.getCursor();
								
								if (c.moveToPosition(newPosition)) {							
									int newTaskList = c.getInt(c.getColumnIndex(GoogleTasksContentProvider.TaskLists.Columns._ID));
									String title = c.getString(c.getColumnIndex(GoogleTasksContentProvider.TaskLists.Columns.TITLE));
									
									if (!(GoogleTaskList.this.currentTaskList == newTaskList)) {
										GoogleTaskList.this.onTaskListChanged(newTaskList, title, newPosition);
									}
								}
							}

							@Override
							public void onAddCallback() {
								// TODO Auto-generated method stub
								
							}}).show();
				}});        
        
        this.synchButton.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				
				GoogleAccountManager m = new GoogleAccountManager(getBaseContext());
				ContentResolver.requestSync(m.getAccounts()[0], GoogleTasksContentProvider.AUTHORITY, new Bundle());
			}});
        
        this.addTaskButton.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View view) {
				
				GoogleTaskList.this.onAddTaskClicked();				
			}});
        
        this.taskTitleEditText = (EditText) this.findViewById(R.id.taskTitleEditText);
        
        this.taskTitleEditText.setOnKeyListener(new OnKeyListener(){

			@Override
			public boolean onKey(View view, int keyCode, KeyEvent event) {
				GoogleTaskList.this.onNewTaskTitleEdited();
				return false;
			}});
        
        loaderManager = this.getSupportLoaderManager();
        
    }
    
    

	@Override
	protected void onStart() {
		super.onStart();
		
        loaderManager.initLoader(DataSets.ACCOUNTS, null, this);
	}

	@Override
	public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {

		CursorLoader cursorLoader = null;
		
		Uri uri = null;		
		String[] projection = null;
		String selection = null;
		String[] selectionArgs = null;
		
		switch(id) {
		
		case DataSets.ACCOUNTS:
			
			uri = GoogleTasksContentProvider.Accounts.CONTENT_URI;
			
			projection = new String[] {GoogleTasksContentProvider.Accounts.Columns._ID
					, GoogleTasksContentProvider.Accounts.Columns.ACCOUNT };
			
			break;
			
		case DataSets.TASKLISTS:
			
			uri = GoogleTasksContentProvider.TaskLists.CONTENT_URI;
			
			projection = new String[] { GoogleTasksContentProvider.TaskLists.Columns.TITLE
					, GoogleTasksContentProvider.TaskLists.Columns.ID
					, GoogleTasksContentProvider.TaskLists.Columns._ID };
			
			selection = GoogleTasksContentProvider.TaskLists.Columns.ACCOUNT + " = ? ";
			selectionArgs = new String[] { currentAccount };			
			break;
			
		case DataSets.TASKS:
			
			uri = GoogleTasksContentProvider.Tasks.CONTENT_URI;
			/*
			projection = new String[] { GoogleTasksContentProvider.Tasks.Columns._ID
					, GoogleTasksContentProvider.Tasks.Columns.TITLE
					, GoogleTasksContentProvider.Tasks.Columns.STATUS };
			*/
			selection = GoogleTasksContentProvider.Tasks.Columns.ACCOUNT + " = ? " 
				+ " AND " + GoogleTasksContentProvider.Tasks.Columns.TASKLIST + " = ?"
				+ " AND " + GoogleTasksContentProvider.Tasks.Columns.DELETED + " = 0"
				+ " AND " + GoogleTasksContentProvider.Tasks.Columns.HIDDEN + " = 0"
				+ " AND TRIM(" + GoogleTasksContentProvider.Tasks.Columns.TITLE + ") != ''";
			
			selectionArgs = new String[] { currentAccount, Integer.toString(currentTaskList) };			
			
			break;
		}
		
		cursorLoader = new CursorLoader(this.getBaseContext()
				, uri
				, projection
				, selection
				, selectionArgs
				, null);
		
		return cursorLoader;
	}

	@Override
	public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {		
		
		switch(cursorLoader.getId()) {
		
		case DataSets.ACCOUNTS:
			onAccountsChanged(cursor);
			break;
		
		case DataSets.TASKLISTS:
			this.onTaskListsChanged(cursor);
			break;
			
		case DataSets.TASKS:
			this.taskAdapter.swapCursor(cursor);
			
			if (this.jumpToLastTask) {
				this.taskListView.setSelectionFromTop(taskAdapter.getCount() - 1, 0);
				this.jumpToLastTask = false;
			}
			break;
		}
	}

	@Override
	public void onLoaderReset(Loader<Cursor> cursorLoader) {
		
		switch(cursorLoader.getId()) {
		
		case DataSets.ACCOUNTS:
			this.accountAdapter.swapCursor(null);
			break;
			
		case DataSets.TASKLISTS:
			this.taskListAdapter.swapCursor(null);
			break;
			
		case DataSets.TASKS:
			this.taskAdapter.swapCursor(null);
			break;
		}
	}

	private void onAccountsChanged(Cursor cursor){

		this.accountAdapter.swapCursor(cursor);
		String newAccount = null;
		int position = -1;
		
		if (cursor.moveToFirst()) {		
			
			do {
				
				position++;
				newAccount = cursor.getString(cursor.getColumnIndex(GoogleTasksContentProvider.Accounts.Columns.ACCOUNT));
				
				if (this.currentAccount == null || this.currentAccount.equals(newAccount)) {
					break;
				} else {
					newAccount = null;
				}				
			} while (cursor.moveToNext());
		}
		
		if (!TextUtils.equals(this.currentAccount, newAccount)) {
			this.onAccountChanged(newAccount, position);
		}
	}
	
	private void onAccountChanged(String newAccount, int position) {
		
		this.currentAccount = newAccount;
		this.currentAccountPosition = position;
		
		/*
		if (newAccount != null) {
			this.accountButton.setText(this.currentAccount);
		} else {
			this.accountButton.setText(R.string.google_task_list_account_button_label);
		}
		*/
		
		this.loaderManager.restartLoader(DataSets.TASKLISTS, null, this);
	}
	
	private void onTaskListsChanged(Cursor cursor){

		this.taskListAdapter.swapCursor(cursor);
		int newTaskList = 0;
		String title = null;
		int position = -1;
		
		if (cursor.moveToFirst()) {		
			
			do {
				
				position++;
				newTaskList = cursor.getInt(cursor.getColumnIndex(GoogleTasksContentProvider.TaskLists.Columns._ID));
				title = cursor.getString(cursor.getColumnIndex(GoogleTasksContentProvider.TaskLists.Columns.TITLE));
				
				if (this.currentTaskList == 0 || this.currentTaskList == newTaskList) {
					break;
				}
			} while (cursor.moveToNext());
		}
		
		if (!(this.currentTaskList == newTaskList)) {
			this.onTaskListChanged(newTaskList, title, position);
		}
	}
	
	private void onTaskListChanged(int newTaskList, String title, int position){
		
		this.currentTaskList = newTaskList;
		this.currentTaskListPosition = position;
		
		if (newTaskList > 0) {
			this.taskListButton.setText(title);
		} else {
			this.taskListButton.setText(R.string.google_task_list_tasklist_button_label);
		}
		
		this.loaderManager.restartLoader(DataSets.TASKS, null, this);
	}
	
	private void onCondensedTaskClicked(View view, int position, long id) {
		
		CondensedTaskViewHelper h = (CondensedTaskViewHelper) view.getTag();
		h.taskWrapper.invertStatus();
		
		this.getContentResolver().update(GoogleTasksContentProvider.Tasks.CONTENT_URI
				, h.taskWrapper.getContentValues()
				, GoogleTasksContentProvider.Tasks.Columns._ID + " = ?"
				, new String[]{ Long.toString(h.taskWrapper.get_id()) } );
	}
	
	private void onAddTaskClicked(){
		
		Task task = new Task();
		TaskWrapper taskWrapper = new TaskWrapper(this.currentAccount, this.currentTaskList, task);
		taskWrapper.setNew(true);
		
		Cursor cursor = this.taskAdapter.getCursor();
		
		if (cursor != null && cursor.moveToLast()) {
			taskWrapper.setPrevious(cursor.getInt(cursor.getColumnIndex(GoogleTasksContentProvider.Tasks.Columns._ID)));
		}		
		
		task.setUpdated(GoogleTasksContentProvider.getTimeStamp());
		task.setTitle(this.taskTitleEditText.getText().toString());		
		task.setStatus(GoogleTasksContentProvider.Tasks.Status.NEEDSACTION);		
		task.setPosition("99999999999999999999");
		
		this.jumpToLastTask = true;
		this.taskTitleEditText.setText("");
		this.addTaskButton.setEnabled(false);
		
		this.getContentResolver().insert(GoogleTasksContentProvider.Tasks.CONTENT_URI
				, taskWrapper.getContentValues());		
	}
	
	private void onNewTaskTitleEdited(){
		if (this.taskTitleEditText.getText().length() > 0) {
			this.addTaskButton.setEnabled(true);
		} else {
			this.addTaskButton.setEnabled(false);
		}
	}
	
	private String getCurrentAccount(){
		
		if (currentAccount==null) {
			return this.getBaseContext().getResources().getString(R.string.google_task_list_account_button_label);
		}		
		return currentAccount;
	}

	private class PickerDialog extends Dialog {
		
		protected View view;
		
		/**
		 * 
		 * @param context
		 * @param title dialog title
		 * @param addText text label for add button
		 * @param adapter
		 * @param position
		 * @param callback
		 */
		public PickerDialog(final Context context
				, final CharSequence title
				, final CharSequence addText
				, final ListAdapter adapter
				, final int position
				, final int layout
				, final PickerCallback callback) {
			
			super(context);
			
			//this.setTitle(title);
			this.requestWindowFeature(Window.FEATURE_NO_TITLE);
			LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			
			view = inflater.inflate(layout, null);
						
			ListView listView = (ListView) view.findViewById(R.id.listView);
			listView.setAdapter(adapter);
			listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
			listView.setItemChecked(position, true);
			listView.setOnItemClickListener(new OnItemClickListener(){

				@Override
				public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
					callback.onItemClickCallback(position);
					PickerDialog.this.dismiss();
				}});
			
			adapter.registerDataSetObserver(new ScrollToBottomObserver(listView));
			
			this.setContentView(view);
		}
		
		private class ScrollToBottomObserver extends DataSetObserver {
			
			private ListView listView;
			
			public ScrollToBottomObserver(ListView listView) {
				this.listView = listView;
			}

			@Override
			public void onChanged() {
				scrollToBottom();
			}
			
			private void scrollToBottom() {
				if (GoogleTaskList.this.jumpToLastTaskList) {
					GoogleTaskList.this.jumpToLastTask = false;
				}	
				listView.setSelectionFromTop(listView.getAdapter().getCount() - 1, 0);
			}			
		}
	}
	
	private class TaskListPickerDialog extends PickerDialog {
		
		private Button accountButton;		
		private Button addTaskListButton;
		private EditText taskListTitleEditText;

		public TaskListPickerDialog(int position, PickerCallback callback) {
			
			super(GoogleTaskList.this
					, GoogleTaskList.this.getText(R.string.google_task_list_tasklist_dialog_label)
					, GoogleTaskList.this.getText(R.string.google_task_list_add_tasklist_button_label)
					, GoogleTaskList.this.taskListAdapter
					, position
					, R.layout.tasklistpicker, callback);
			
			this.accountButton = (Button) this.view.findViewById(R.id.accountButton);
			this.accountButton.setText(GoogleTaskList.this.getCurrentAccount());
			this.accountButton.setOnClickListener(new View.OnClickListener(){

				@Override
				public void onClick(View v) {
					new AccountPickerDialog(currentAccountPosition
							, new PickerCallback(){

								@Override
								public void onItemClickCallback(int newPosition) {
									
									Cursor c = GoogleTaskList.this.accountAdapter.getCursor();
									
									if (c.moveToPosition(newPosition)) {
										String newAccount = c.getString(c.getColumnIndex(GoogleTasksContentProvider.Accounts.Columns.ACCOUNT));
										
										if (!TextUtils.equals(GoogleTaskList.this.currentAccount, newAccount)) {
											GoogleTaskList.this.onAccountChanged(newAccount, newPosition);
											TaskListPickerDialog.this.accountButton.setText(GoogleTaskList.this.getCurrentAccount());
										}									
									}
								}

								@Override
								public void onAddCallback() {
									// TODO Auto-generated method stub
									
								}}).show();
				}});
			
			this.taskListTitleEditText = (EditText) this.findViewById(R.id.taskListTitleEditText);
			this.taskListTitleEditText.setOnKeyListener(new View.OnKeyListener(){

				@Override
				public boolean onKey(View view, int keyCode, KeyEvent event) {
					TaskListPickerDialog.this.onNewTaskTitleEdited();
					return false;
				}});
			
			this.addTaskListButton = (Button) this.findViewById(R.id.addTaskListButton);
			this.addTaskListButton.setEnabled(false);
			this.addTaskListButton.setOnClickListener(new View.OnClickListener() {
				
				@Override
				public void onClick(View v) {
					TaskListPickerDialog.this.onAddTaskListClicked();
				}
			});
		}
		
		private void onNewTaskTitleEdited(){
			if (this.taskListTitleEditText.getText().length() > 0) {
				this.addTaskListButton.setEnabled(true);
			} else {
				this.addTaskListButton.setEnabled(false);
			}
		}
		
		private void onAddTaskListClicked(){
			
			TaskList taskList = new TaskList();
			taskList.setTitle(this.taskListTitleEditText.getText().toString());
			taskList.setUpdated(GoogleTasksContentProvider.getTimeStamp());
			
			this.taskListTitleEditText.setText("");
			this.addTaskListButton.setEnabled(false);
			
			TaskListWrapper taskListWrapper = new TaskListWrapper(GoogleTaskList.this.currentAccount, taskList);
			taskListWrapper.setNew(true);
			
			GoogleTaskList.this.jumpToLastTaskList = true;
			GoogleTaskList.this.getContentResolver().insert(GoogleTasksContentProvider.TaskLists.CONTENT_URI, taskListWrapper.getContentValues());
		}
	}
	
	private class AccountPickerDialog extends PickerDialog {

		public AccountPickerDialog(int position, PickerCallback callback) {
			super(GoogleTaskList.this
					, GoogleTaskList.this.getText(R.string.google_task_list_account_dialog_label)
					, GoogleTaskList.this.getText(R.string.google_task_list_add_account_button_label)
					, GoogleTaskList.this.accountAdapter					
					, position
					, R.layout.accountpicker
					, callback);
		}
	}
	
	private interface PickerCallback {
		public void onItemClickCallback(int newPosition);
		public void onAddCallback();
	}
	
	private class CondensedTaskCursorAdapter extends CursorAdapter {
		
		private LayoutInflater layoutInflater;
		
		public CondensedTaskCursorAdapter(Context context) {
			super(context, null, false);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			
			if (layoutInflater == null) {
				layoutInflater = LayoutInflater.from(context);
			}
			
			View view = layoutInflater.inflate(R.layout.condensedtask, parent, false);
			CondensedTaskViewHelper h = new CondensedTaskViewHelper();
			h.title = (TextView) view.findViewById(R.id.title);
			//h.status = (CheckBox) view.findViewById(R.id.status);
			h.taskWrapper = new TaskWrapper();
			view.setTag(h);

			return view;
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			
			CondensedTaskViewHelper h = (CondensedTaskViewHelper) view.getTag();
			
			h.taskWrapper.setFromCursor(cursor);
			h.title.setText(h.taskWrapper.getTask().getTitle());
			
			boolean isChecked = GoogleTasksContentProvider.Tasks.Status.statusToBool(h.taskWrapper.getTask().getStatus());
			
			if (isChecked) {
				h.title.setPaintFlags(h.title.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
			} else {
				h.title.setPaintFlags(h.title.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
			}
		}
		
	}
	
	private class CondensedTaskViewHelper {
		public TaskWrapper taskWrapper;
		public TextView title;
	}
}
